home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / asm / adisv1_3.lha / src / opcode_handler_fpu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-20  |  8.8 KB  |  340 lines

  1. /*
  2.  * Change history:
  3.  * $Log:    opcode_handler_fpu.c,v $
  4.  * Revision 3.0  93/09/24  17:54:15  Martin_Apel
  5.  * New feature: Added extra 68040 FPU opcodes
  6.  * 
  7.  * Revision 2.1  93/07/18  22:56:24  Martin_Apel
  8.  * *** empty log message ***
  9.  * 
  10.  * Revision 2.0  93/07/01  11:54:27  Martin_Apel
  11.  * *** empty log message ***
  12.  * 
  13.  * Revision 1.7  93/06/16  20:29:03  Martin_Apel
  14.  * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
  15.  * Minor mod.: Added variables for 68030 / 040 support
  16.  * 
  17.  * Revision 1.6  93/06/06  13:47:37  Martin_Apel
  18.  * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3
  19.  * 
  20.  * Revision 1.5  93/05/27  20:48:41  Martin_Apel
  21.  * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM
  22.  *          instructions.
  23.  * 
  24.  */
  25.  
  26. #include <exec/types.h>
  27. #include <string.h>
  28. #include "defs.h"
  29.  
  30. static char rcsid [] = "$Id: opcode_handler_fpu.c,v 3.0 93/09/24 17:54:15 Martin_Apel Exp $";
  31.  
  32. int fpu (struct opcode_entry *op)
  33.  
  34. {
  35. int used;
  36. char *reg_list,
  37.      *ea;
  38. register char *tmp;
  39. int num_regs;
  40.  
  41. if ((*(code + 1) & 0xfc00) == 0x5c00)
  42.   {
  43.   /* FMOVECR */
  44.   if (pass3)
  45.     {
  46.     strcpy (opcode, "FMOVECR.X");
  47.     immed (src, (long)(*(code + 1) & 0x7f));
  48.     strcpy (dest, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]);
  49.     }
  50.   return (2);
  51.   }
  52. else
  53.   {
  54.   switch (*(code + 1) >> 13)
  55.     {
  56.     case 0:
  57.     case 2: if ((*(code + 1) & 0x0040) && !mc68040)
  58.               return (TRANSFER);
  59.             op = &(fpu_opcode_table [*(code + 1) & 0x7f]);
  60.             return ((*op->handler) (op));
  61.  
  62.     case 3: /* FMOVE from FPx */
  63.             if (pass3)
  64.               {
  65.               strcpy (opcode, "FMOVE");
  66.               strcat (opcode, xfer_size [(*(code + 1) >> 10) & 0x7]);
  67.               strcpy (src, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]);
  68.               }
  69.             used = decode_ea (MODE_NUM (*code), REG_NUM (*code), dest, 
  70.                               sizes [(*(code + 1) >> 10) & 0x7], (short)2);
  71.             if ((*(code + 1) & 0x1c00) == 0x0c00)
  72.               {
  73.               /* Packed decimal real with static k-factor */
  74.               if (pass3)
  75.                 {
  76.                 tmp = dest + strlen (dest);
  77.                 *tmp++ = '{';
  78.                 tmp = immed (tmp, (long)(*(code + 1) & 0x7f));
  79.                 *tmp++ = '}';
  80.                 *tmp = 0;
  81.                   /* Same as:
  82.                      sprintf (dest + strlen (dest), "{#$%x}", 
  83.                               *(code + 1) & 0x7f);
  84.                   */
  85.                 }
  86.               }
  87.             else if ((*(code + 1) & 0x1c00) == 0x1c00)
  88.               {
  89.               /* Packed decimal real with dynamic k-factor */
  90.               if (pass3)
  91.                 {
  92.                 tmp = dest + strlen (dest);
  93.                 *tmp++ = '{';
  94.                 strcpy (tmp, reg_names [(*(code + 1) >> 4) & 0x7]);
  95.                 while (*(++tmp) != 0);
  96.                 *tmp++ = '}';
  97.                 *tmp = 0;
  98.                 /* Same as:
  99.                    sprintf (dest + strlen (dest), "{%s}", 
  100.                             reg_names [(*(code + 1) >> 4) & 0x7]);
  101.                 */
  102.                 }
  103.               }
  104.             return (2 + used);
  105.  
  106.     case 4: 
  107.     case 5: /* FMOVE cntrl regs */
  108.             num_regs = 0;
  109.             if (pass3)
  110.               strcpy (opcode, "FMOVE");
  111.             if (*(code + 1) & 0x2000)
  112.               {
  113.               ea = dest;
  114.               reg_list = src;
  115.               }
  116.             else
  117.               {
  118.               ea = src;
  119.               reg_list = dest;
  120.               }
  121.             used = decode_ea (MODE_NUM (*code), REG_NUM (*code), ea, 
  122.                               (short)(ACC_DATA | ACC_LONG), (short)2);
  123.             if (pass3)
  124.               {
  125.               if (*(code + 1) & 0x1000)
  126.                 {
  127.                 strcpy (reg_list, "FPCR");
  128.                 num_regs++;
  129.                 }
  130.               if (*(code + 1) & 0x0800)
  131.                 {
  132.                 if (num_regs != 0)
  133.                   strcat (reg_list, "/");
  134.                 strcat (reg_list, "FPSR");
  135.                 num_regs++;
  136.                 }
  137.               if (*(code + 1) & 0x0400)
  138.                 {
  139.                 if (num_regs != 0)
  140.                   strcat (reg_list, "/");
  141.                 strcat (reg_list, "FPIAR");
  142.                 num_regs++;
  143.                 }
  144.               if (num_regs > 1)
  145.                 strcat (opcode, "M");          /* for FMOVEM */
  146.               }
  147.             return (2 + used);
  148.  
  149.     case 6:
  150.     case 7: /* FMOVEM */
  151.             if (MODE_NUM (*code) < 2)
  152.               return (TRANSFER);
  153.             if (pass3)
  154.               strcpy (opcode, "FMOVEM.X");
  155.             if (*(code + 1) & 0x2000)        /* to mem */
  156.               {
  157.               if (MODE_NUM (*code) == 3 || (*code & 0x3f) >= 0x3a)
  158.                 return (TRANSFER);
  159.               reg_list = src;
  160.               ea = dest;
  161.               }
  162.             else                             /* from mem */
  163.               {
  164.               if (MODE_NUM (*code) == 4 || (*code & 0x3f) == 0x3a)
  165.                 return (TRANSFER);
  166.               reg_list = dest;
  167.               ea = src;
  168.               }
  169.             if (pass3)
  170.               {
  171.               if (*(code + 1) & 0x0800)
  172.                 {
  173.                 /* Dynamic register list in data register */
  174.                 strcpy (reg_list, reg_names [(*(code + 1) >> 4) & 0x7]);
  175.                 }
  176.               else
  177.                 {
  178.                 /* Test for predecrement mode */
  179.                 if (MODE_NUM (*code) == 4)
  180.                   format_reg_list (reg_list, (unsigned short)(*(code + 1) & 0xff),
  181.                                    TRUE, (short) 17);
  182.                 else
  183.                   format_reg_list (reg_list, (unsigned short)(*(code + 1) << 8),
  184.                                    FALSE, (short) 17);
  185.                 }
  186.               }
  187.             return (decode_ea (MODE_NUM (*code), REG_NUM (*code), ea,
  188.                                ACC_DATA, (short)2) + 2);
  189.     }
  190.   }
  191. return (TRANSFER);
  192. }
  193.  
  194.  
  195. int std_fpu (struct opcode_entry *op)
  196.  
  197. {
  198. if (pass3)
  199.   {
  200.   strcpy (opcode, op->mnemonic);
  201.   strcpy (dest, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]);
  202.   }
  203. if (*(code + 1) & 0x4000)          /* R/M - Bit */
  204.   {
  205.   if (pass3)
  206.     strcat (opcode, xfer_size [(*(code + 1) >> 10) & 0x7]);
  207.   return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, 
  208.                      sizes [(*(code + 1) >> 10) & 0x7], (short)2) + 2);
  209.   }
  210. else if (pass3)
  211.   {
  212.   strcat (opcode, xfer_size [2]);       /* ".X" */
  213.   strcpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]);
  214.   }
  215.  
  216. if ((src [2] == dest [2]) && (op->param == SNG_ALL))      /* single operand */
  217.   dest [0] = 0;
  218. return (2);
  219. }
  220.  
  221.  
  222. int fsincos (struct opcode_entry *op)
  223.  
  224. {
  225. if (pass3)
  226.   {
  227.   strcpy (opcode, op->mnemonic);
  228.   strcpy (dest, reg_names [17 + op->param]);
  229.   strcat (dest, ":");
  230.   strcat (dest, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]);
  231.   }
  232. if (*(code + 1) & 0x4000)          /* R/M-Bit */
  233.   {
  234.   if (pass3)
  235.     strcat (opcode, xfer_size [(*(code + 1) >> 10) & 0x7]);
  236.   return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, 
  237.                      sizes [(*(code + 1) >> 10) & 0x7], (short)2) + 2);  
  238.   }
  239. else
  240.   {
  241.   if (pass3)
  242.     {
  243.     strcat (opcode, xfer_size [2]);       /* ".X" */
  244.     strcpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]);
  245.     }
  246.   return (2);
  247.   }
  248. }
  249.  
  250.  
  251. int fscc (struct opcode_entry *op)
  252.  
  253. {
  254. if ((*(code + 1) & 0xffe0) != 0)
  255.   return (TRANSFER);
  256.  
  257. if (pass3)
  258.   strcat (opcode, fpu_conditions [*(code + 1)]);
  259. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, ACC_BYTE, (short)2)
  260.           + 2);
  261. }
  262.  
  263.  
  264. int fbranch (struct opcode_entry *op)
  265.  
  266. {
  267. long offset;
  268. unsigned long ref;
  269.  
  270. if (pass3)
  271.   strcat (opcode, fpu_conditions [*code & 0x1f]);
  272. if (op->param & ACC_WORD)
  273.   offset = (short)*(code + 1);
  274. else
  275.   offset = (*(code + 1) << 16) + *(code + 2);
  276.  
  277. if (offset == 0 && pass3)
  278.   strcpy (opcode, "FNOP");
  279. else if (offset != 0)
  280.   {
  281.   ref = current_address + 2 + offset;
  282.   if (ref < first_address || ref > last_address)
  283.     return (TRANSFER);
  284.   if (pass3)
  285.     gen_label (src, ref, TRUE);
  286.   else
  287.     enter_ref (ref, 0L, ACC_CODE);
  288.   }
  289. return (2 + ((op->param & ACC_WORD) ? 0 : 1));
  290. }
  291.  
  292.  
  293. int fdbranch (struct opcode_entry *op)
  294.  
  295. {
  296. unsigned long ref;
  297.  
  298. if ((*(code + 1) & 0xffe0) != 0)
  299.   return (TRANSFER);
  300. if ((*code & 0x0038) != 0x8)
  301.   return (TRANSFER);
  302. if (pass3)
  303.   {
  304.   strcat (opcode, fpu_conditions [*(code + 1)]);
  305.   strcpy (src, reg_names [*code & 0x7]);
  306.   }
  307. ref = current_address + 4 + (short)*(code + 2);
  308. if (ref < first_address || ref > last_address)
  309.   return (TRANSFER);
  310. if (pass3)
  311.   gen_label (dest, ref, TRUE);
  312. else
  313.   enter_ref (ref, 0L, ACC_CODE);
  314. return (3);
  315. }
  316.  
  317.  
  318. int ftrapcc (struct opcode_entry *op)
  319.  
  320. {
  321. if ((*(code + 1) & 0xffe0) != 0)
  322.   return (TRANSFER);
  323. if (pass3)
  324.   strcat (opcode, fpu_conditions [*(code + 1)]);
  325. if ((*code & 0x7) == 2)
  326.   {
  327.   if (pass3)
  328.     immed (src, (long)*(code + 2));
  329.   return (3);
  330.   }
  331. if ((*code & 0x7) == 3)
  332.   {
  333.   if (pass3)
  334.     immed (src, (*(code + 2) << 16) + *(code + 3));
  335.   return (4);
  336.   }
  337.  
  338. return (2);
  339. }
  340.